<template>
  <div class="dict-management-page">
    <div class="page-header">
      <div class="header-left">
        <h1>字典管理</h1>
        <p>管理系统字典分类和数据字典</p>
      </div>
      <el-button type="primary" :icon="Plus" @click="showAddCategoryDialog = true">
        新增分类
      </el-button>
    </div>

    <div class="dict-layout">
      <!-- 左侧字典分类 -->
      <div class="dict-categories">
        <el-card shadow="never">
          <template #header>
            <div class="category-header">
              <span>字典分类 ({{ dictCategories.length }})</span>
              <el-button size="small" :icon="Refresh" @click="refreshData">刷新</el-button>
            </div>
          </template>

          <div class="category-list">
            <div v-for="category in dictCategories" :key="category.id"
              :class="['category-item', { active: selectedCategory?.id === category.id }]"
              @click="selectCategory(category)">
              <div class="category-info">
                <h4>{{ category.name }}</h4>
                <p>{{ category.description }}</p>
                <div class="category-meta">
                  <el-tag :type="category.status === 'enabled' ? 'success' : 'info'" size="small">
                    {{ category.status === 'enabled' ? '启用' : '禁用' }}
                  </el-tag>
                  <span class="item-count">
                    {{ category.itemCount || 0 }} 条字典
                  </span>
                </div>
              </div>
              <div class="category-actions">
                <div class="action-buttons">
                  <el-button size="small" :icon="Edit" @click.stop="editCategory(category)">
                    编辑
                  </el-button>
                  <el-button size="small" :icon="Delete" type="danger" @click.stop="deleteCategory(category)">
                    删除
                  </el-button>
                </div>
              </div>
            </div>
          </div>
        </el-card>
      </div>

      <!-- 右侧字典值 -->
      <div class="dict-items">
        <el-card shadow="never">
          <template #header>
            <div class="item-header">
              <span>{{ selectedCategory ? `${selectedCategory.name} - 字典值 (${selectedCategory.itemCount || 0})` :
                '请选择分类' }}</span>
              <el-button v-if="selectedCategory" size="small" type="primary" :icon="Plus"
                @click="showAddItemDialog = true">
                新增字典值
              </el-button>
            </div>
          </template>

          <div v-if="!selectedCategory" class="empty-state">
            <el-icon size="60" color="#ccc">
              <FolderOpened />
            </el-icon>
            <p>请选择左侧字典分类查看具体值</p>
            <p class="empty-hint">或者创建一个新的字典分类</p>
          </div>

          <div v-else class="dict-items-list">
            <el-table :data="filteredDictItems" stripe style="width: 100%" v-loading="tableLoading">
              <el-table-column prop="sortOrder" label="排序" width="80" />
              <el-table-column prop="name" label="名称">
                <template #default="{ row }">
                  <div class="item-name">
                    <strong>{{ row.name }}</strong>
                    <small v-if="row.description">({{ row.description }})</small>
                  </div>
                </template>
              </el-table-column>
              <el-table-column prop="code" label="代码" width="200">
                <template #default="{ row }">
                  <code class="item-code"
                    style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">{{ row.code }}</code>
                </template>
              </el-table-column>
              <el-table-column prop="value" label="值" width="200">
                <template #default="{ row }">
                  <span class="item-value">{{ row.value }}</span>
                </template>
              </el-table-column>
              <el-table-column label="颜色" width="120">
                <template #default="{ row }">
                  <el-tag v-if="row.color" :type="getTagType(row.color)" size="small">
                    {{ row.color }}
                  </el-tag>
                  <span v-else class="text-muted">未设置</span>
                </template>
              </el-table-column>
              <el-table-column prop="status" label="状态" width="100">
                <template #default="{ row }">
                  <el-switch v-model="row.status" active-value="enabled" inactive-value="disabled"
                    @change="updateItemStatus(row)" />
                </template>
              </el-table-column>
              <el-table-column prop="createTime" label="创建时间" width="180">
                <template #default="{ row }">
                  <span style="white-space: nowrap;">{{ formatDate(row.createTime) }}</span>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="180" fixed="right">
                <template #default="{ row }">
                  <div class="table-action-buttons">
                    <el-button size="small" :icon="Edit" @click="editItem(row)" style="margin-right: 8px;">
                      编辑
                    </el-button>
                    <el-button size="small" :icon="Delete" type="danger" @click="deleteItem(row)">
                      删除
                    </el-button>
                  </div>
                </template>
              </el-table-column>
            </el-table>

            <!-- 分页 -->
            <div class="pagination" v-if="filteredDictItems.length > 0">
              <el-pagination v-model:current-page="pagination.page" v-model:page-size="pagination.size"
                :page-sizes="[10, 20, 50, 100]" :total="filteredDictItems.length"
                layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
                @current-change="handleCurrentChange" />
            </div>
          </div>
        </el-card>
      </div>
    </div>

    <!-- 字典分类对话框 -->
    <el-dialog v-model="showAddCategoryDialog" :title="editingCategory ? '编辑字典分类' : '新增字典分类'" width="500px"
      :before-close="handleCategoryCancel">
      <el-form ref="categoryFormRef" :model="categoryForm" :rules="categoryRules" label-width="100px">
        <el-form-item label="分类名称" prop="name">
          <el-input v-model="categoryForm.name" placeholder="请输入分类名称" />
        </el-form-item>

        <el-form-item label="分类代码" prop="code">
          <el-input v-model="categoryForm.code" placeholder="请输入分类代码" />
          <small>用于程序调用，建议使用下划线命名</small>
        </el-form-item>

        <el-form-item label="分类描述">
          <el-input v-model="categoryForm.description" type="textarea" :rows="3" placeholder="请输入分类描述" />
        </el-form-item>

        <el-form-item label="排序">
          <el-input-number v-model="categoryForm.sort" :min="0" style="width: 120px" />
          <small>数字越小排序越靠前</small>
        </el-form-item>

        <el-form-item label="状态">
          <el-radio-group v-model="categoryForm.status">
            <el-radio label="enabled">启用</el-radio>
            <el-radio label="disabled">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="handleCategoryCancel">取消</el-button>
        <el-button type="primary" @click="handleCategorySave" :loading="categorySaving">
          保存
        </el-button>
      </template>
    </el-dialog>

    <!-- 字典值对话框 -->
    <el-dialog v-model="showAddItemDialog" :title="editingItem ? '编辑字典值' : '新增字典值'" width="500px"
      :before-close="handleItemCancel">
      <el-form ref="itemFormRef" :model="itemForm" :rules="itemRules" label-width="100px">
        <el-form-item label="字典名称" prop="name">
          <el-input v-model="itemForm.name" placeholder="请输入字典名称" />
        </el-form-item>

        <el-form-item label="字典代码" prop="code">
          <el-input v-model="itemForm.code" placeholder="请输入字典代码" />
        </el-form-item>

        <el-form-item label="字典值" prop="value">
          <el-input v-model="itemForm.value" placeholder="请输入字典值" />
        </el-form-item>

        <el-form-item label="字典描述">
          <el-input v-model="itemForm.description" type="textarea" :rows="2" placeholder="请输入字典描述（可选）" />
        </el-form-item>

        <el-form-item label="显示颜色">
          <div class="color-input-group">
            <el-select v-model="itemForm.color" placeholder="选择颜色类型" clearable style="width: 160px;">
              <el-option label="蓝色(primary)" value="primary" />
              <el-option label="绿色(success)" value="success" />
              <el-option label="橙色(warning)" value="warning" />
              <el-option label="红色(danger)" value="danger" />
              <el-option label="灰色(info)" value="info" />
              <el-option label="自定义颜色" value="custom" />
            </el-select>
            <el-input 
              v-if="itemForm.color === 'custom'" 
              v-model="itemForm.customColor" 
              placeholder="输入颜色值，如 #409eff"
              style="width: 120px; margin-left: 8px;"
            />
          </div>
          <small>用于前端标签显示，可选择预设颜色或输入自定义颜色值</small>
        </el-form-item>

        <el-form-item label="排序">
          <el-input-number v-model="itemForm.sort" :min="0" style="width: 120px" />
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="handleItemCancel">取消</el-button>
        <el-button type="primary" @click="handleItemSave" :loading="itemSaving">
          保存
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Edit, Delete, FolderOpened, Refresh } from '@element-plus/icons-vue'
import { dictCategoryApi, dictItemApi } from '@/utils/api'

// 页面状态
const tableLoading = ref(false)
const showAddCategoryDialog = ref(false)
const showAddItemDialog = ref(false)
const categorySaving = ref(false)
const itemSaving = ref(false)
const editingCategory = ref(null)
const editingItem = ref(null)
const selectedCategory = ref(null)

// 分页数据
const pagination = ref({
  page: 1,
  size: 10
})

// 表单引用
const categoryFormRef = ref()
const itemFormRef = ref()

// 字典分类表单
const categoryForm = ref({
  name: '',
  code: '',
  description: '',
  sort: 0,
  status: 'enabled'
})

// 字典值表单
const itemForm = ref({
  name: '',
  code: '',
  value: '',
  description: '',
  color: '',
  customColor: '',
  sort: 0
})

// 表单验证规则
const categoryRules = {
  name: [
    { required: true, message: '请输入分类名称', trigger: 'blur' }
  ],
  code: [
    { required: true, message: '请输入分类代码', trigger: 'blur' }
  ]
}

const itemRules = {
  name: [
    { required: true, message: '请输入字典名称', trigger: 'blur' }
  ],
  code: [
    { required: true, message: '请输入字典代码', trigger: 'blur' }
  ],
  value: [
    { required: true, message: '请输入字典值', trigger: 'blur' }
  ]
}

// 字典分类数据
const dictCategories = ref([])

// 字典值数据
const dictItems = ref([])

// 初始化数据
onMounted(async () => {
  await loadDictCategories()
})

// 计算属性：过滤后的字典值
const filteredDictItems = computed(() => {
  if (!selectedCategory.value) return []

  const items = dictItems.value
    .filter(item => item.categoryId === selectedCategory.value.id)
    .sort((a, b) => a.sort - b.sort)

  // 分页处理
  const start = (pagination.value.page - 1) * pagination.value.size
  const end = start + pagination.value.size
  return items.slice(start, end)
})

// 方法

// 选择分类
const selectCategory = async (category) => {
  // 如果已选中当前分类，不重复加载
  if (selectedCategory.value?.id === category.id) {
    return
  }

  selectedCategory.value = category
  pagination.value.page = 1 // 重置分页
  await loadDictItems(category.id)
}

// 刷新数据
const refreshData = async () => {
  tableLoading.value = true
  try {
    await loadDictCategories()
    if (selectedCategory.value) {
      await loadDictItems(selectedCategory.value.id)
    }
    ElMessage.success('数据已刷新')
  } catch (error) {
    console.error('刷新数据失败:', error)
  } finally {
    tableLoading.value = false
  }
}

// 加载字典分类
const loadDictCategories = async () => {
  try {
    const result = await dictCategoryApi.queryList({})
    dictCategories.value = result.data || []
    // 如果有选中的分类，刷新对应分类下的字典值
    if (selectedCategory.value && !dictCategories.value.find(c => c.id === selectedCategory.value.id)) {
      selectedCategory.value = null
    }
  } catch (error) {
    console.error('加载字典分类失败:', error)
  }
}

// 加载字典值
const loadDictItems = async (categoryId) => {
  try {
    const result = await dictItemApi.queryByCategoryId(categoryId)
    const categoryItems = result.data || []
    // 更新对应分类下的字典值
    const otherItems = dictItems.value.filter(item => item.categoryId !== categoryId)
    dictItems.value = [...otherItems, ...categoryItems]
  } catch (error) {
    console.error('加载字典值失败:', error)
  }
}



// 新增字典分类
const handleCategorySave = async () => {
  try {
    await categoryFormRef.value.validate()

    categorySaving.value = true

    if (editingCategory.value) {
      // 编辑模式
      await dictCategoryApi.update(editingCategory.value.id, categoryForm.value)
    } else {
      // 新增模式
      await dictCategoryApi.create(categoryForm.value)
    }

    ElMessage.success(editingCategory.value ? '分类更新成功' : '分类添加成功')
    await loadDictCategories()
    handleCategoryCancel()

  } catch (error) {
    console.error('保存失败:', error)
  } finally {
    categorySaving.value = false
  }
}

// 取消分类操作
const handleCategoryCancel = () => {
  showAddCategoryDialog.value = false
  editingCategory.value = null
  categoryForm.value = {
    name: '',
    code: '',
    description: '',
    sort: 0,
    status: 'enabled'
  }
  categoryFormRef.value?.clearValidate()
}

// 编辑分类
const editCategory = (category) => {
  editingCategory.value = category
  Object.assign(categoryForm.value, category)
  showAddCategoryDialog.value = true
}

// 删除分类
const deleteCategory = async (category) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除分类「${category.name}」吗？这将同时删除该分类下的所有字典值。`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    await dictCategoryApi.delete(category.id)
    // 删除该分类下的所有字典值
    const itemIds = dictItems.value
      .filter(item => item.categoryId === category.id)
      .map(item => item.id)

    if (itemIds.length > 0) {
      await dictItemApi.deleteBatch(itemIds)
    }

    // 刷新数据
    await loadDictCategories()
    dictItems.value = dictItems.value.filter(item => item.categoryId !== category.id)

    // 如果删除的是当前选中的分类，清除选中
    if (selectedCategory.value?.id === category.id) {
      selectedCategory.value = null
    }

    ElMessage.success('删除成功')
  } catch {
    // 用户取消删除
  }
}

// 保存字典值
const handleItemSave = async () => {
  try {
    await itemFormRef.value.validate()

    if (!selectedCategory.value) {
      ElMessage.error('请先选择字典分类')
      return
    }

    itemSaving.value = true

    const requestData = {
      ...itemForm.value,
      categoryId: selectedCategory.value.id,
      color: itemForm.value.color === 'custom' ? itemForm.value.customColor : itemForm.value.color
    }
    
    // 移除不必要的字段
    delete requestData.customColor

    if (editingItem.value) {
      // 编辑模式
      await dictItemApi.update(editingItem.value.id, requestData)
    } else {
      // 新增模式
      await dictItemApi.create(requestData)
    }

    ElMessage.success(editingItem.value ? '字典值更新成功' : '字典值添加成功')
    await loadDictItems(selectedCategory.value.id)
    handleItemCancel()

  } catch (error) {
    console.error('保存失败:', error)
  } finally {
    itemSaving.value = false
  }
}

// 取消字典值操作
const handleItemCancel = () => {
  showAddItemDialog.value = false
  editingItem.value = null
  itemForm.value = {
    name: '',
    code: '',
    value: '',
    description: '',
    color: '',
    customColor: '',
    sort: 0
  }
  itemFormRef.value?.clearValidate()
}

// 编辑字典值
const editItem = (item) => {
  editingItem.value = item
  Object.assign(itemForm.value, item)
  
  // 如果color不是custom，清空customColor
  if (itemForm.value.color !== 'custom') {
    itemForm.value.customColor = ''
  }
  
  showAddItemDialog.value = true
}

// 删除字典值
const deleteItem = async (item) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除字典值「${item.name}」吗？`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    await dictItemApi.delete(item.id)
    await loadDictItems(selectedCategory.value.id)
    ElMessage.success('删除成功')
  } catch {
    // 用户取消删除
  }
}

// 更新字典值状态
const updateItemStatus = async (item) => {
  try {
    await dictItemApi.update(item.id, item)
    ElMessage.success(`字典值已${item.status === 'enabled' ? '启用' : '禁用'}`)
  } catch (error) {
    console.error('状态更新失败:', error)
    // 如果更新失败，恢复原状态
    item.status = item.status === 'enabled' ? 'disabled' : 'enabled'
  }
}

// 分页事件
const handleSizeChange = (size) => {
  pagination.value.size = size
  pagination.value.page = 1
}

const handleCurrentChange = (page) => {
  pagination.value.page = page
}

// 工具函数
const getTagType = (color) => {
  const validTypes = ['primary', 'success', 'warning', 'danger', 'info']
  return validTypes.includes(color) ? color : 'info'
}

const formatDate = (date) => {
  return date
}
</script>

<style scoped>
.dict-management-page {
  padding: 0;
}

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.header-left h1 {
  font-size: 28px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 8px;
}

.header-left p {
  color: #606266;
  font-size: 14px;
}

.dict-layout {
  display: flex;
  gap: 20px;
  min-height: 500px;
}

.dict-categories {
  flex: 1;
  max-width: 350px;
}

.dict-items {
  flex: 2;
}

.category-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.category-list {
  max-height: 450px;
  overflow-y: auto;
}

.category-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 16px;
  border: 1px solid #ebeef5;
  border-radius: 6px;
  margin-bottom: 12px;
  cursor: pointer;
  transition: all 0.3s;
  min-height: 80px;
}

.category-item .category-info {
  flex: 1;
  margin-right: 16px;
}

.category-item .category-actions {
  flex-shrink: 0;
}

.category-item:hover {
  border-color: #c0c4cc;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.category-item.active {
  border-color: #409eff;
  background-color: #f0f9ff;
}

.category-info h4 {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 4px;
}

.category-info p {
  font-size: 12px;
  color: #606266;
  margin-bottom: 8px;
  margin: 0;
}

.category-meta {
  display: flex;
  align-items: center;
  gap: 8px;
}

.item-count {
  font-size: 11px;
  color: #909399;
}

.category-actions {
  opacity: 0;
  transition: opacity 0.3s;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  min-height: 60px;
}

.category-item:hover .category-actions {
  opacity: 1;
}

.item-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 300px;
  color: #909399;
}

.empty-state p {
  margin-top: 16px;
  font-size: 14px;
}

.empty-hint {
  font-size: 12px;
  color: #c0c4cc;
  margin-top: 8px;
}

.dict-items-list {
  max-height: 450px;
  overflow-y: auto;
}

.item-name strong {
  font-size: 14px;
  color: #303133;
}

.item-name small {
  display: block;
  color: #909399;
  font-size: 12px;
  margin-top: 2px;
}

.item-code {
  background: #f5f7fa;
  padding: 2px 6px;
  border-radius: 4px;
  font-family: 'Monaco', 'Courier New', monospace;
  font-size: 12px;
  color: #409eff;
}

.item-value {
  font-weight: 500;
  color: #303133;
}

.pagination {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

small {
  display: block;
  color: #909399;
  font-size: 12px;
  margin-top: 4px;
}

.action-buttons {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 60px;
}

.action-buttons .el-button {
  width: 70px;
  text-align: center;
  line-height: 1;
  padding: 5px 8px;
  font-size: 12px;
  height: 26px;
  min-height: 26px;
  margin: 0;
}

.table-action-buttons {
  display: flex;
  align-items: center;
}

.color-input-group {
  display: flex;
  align-items: center;
  gap: 8px;
}

.text-muted {
  color: #909399;
  font-size: 12px;
  font-style: italic;
}
</style>